#include <cassert>
#include <xscript/xprint.h>
#include <astree/xabstractsyntaxtreelet.h>
#include <astree/xabstractsyntaxtreecreator_let.h>
#include <astree/xabstractsyntaxtreeparser.h>

bool XAbstractSyntaxTreeCreator_Let::isMatched(const XTokenBlock& tokens, uint32_t row, uint32_t col) {
    auto list = tokens.at(row).tokens;
    return list.at(0)->getString() == L"let";
}

std::shared_ptr<XAbstractSyntaxTree> XAbstractSyntaxTreeCreator_Let::create(const XTokenBlock& tokens, uint32_t row, uint32_t col, std::shared_ptr<XAbstractSyntaxTreeBuilder> builder) {
    skipToCol = 0;
    skipToRow ++;

    auto list = tokens.at(row);
    bool findEqual = false;

    std::vector<XTokenPtr> variables, values;
    for (size_t i = 1; i < list.tokens.size(); i++) {
        auto token = list.tokens.at(i);
        if (findEqual == false && token->getString() == L"=")
            findEqual = true;
        else if (findEqual == false)
            variables.push_back(token);
        else if (findEqual)
            values.push_back(token);
    }

    auto token = list.tokens.at(0);

    if (variables.empty() || values.empty()) {
        XScriptExecutor::getInstance()->setError(XError::XError_BadBlockError, token->toString());
        return nullptr;
    }

    std::shared_ptr<XAbstractSyntaxTreeLet> let = std::make_shared<XAbstractSyntaxTreeLet>(token);

    {
        XAbstractSyntaxTreeParserVariable parser;
        auto value = parser.parse(variables);
        if (value) {
            let->addChild(value);
        } else {
            return nullptr;
        }
    }

    {
        XAbstractSyntaxTreeParserValue parser;
        auto value = parser.parse(values);
        if (value) {
            let->addChild(value);
        } else
            return nullptr;
    }

    if (let->getChildCount() != 2) {
        XScriptExecutor::getInstance()->setError(XError::XError_BadBlockError, token->toString());
        return nullptr;
    }

    return let;
}
